#![doc = include_str!("../README.md")]

use self::data::*;
use anyhow::{anyhow, Result};
use umya_spreadsheet::Worksheet;

/// xlsx写入的相关工具
pub mod xlsx_util;

#[cfg(feature = "date")]
/// 工具方法
pub mod date_util;

//#[cfg(feature = "encrypt")]
/// 加密工具
//pub mod encrypt;

/// 相关数据
pub mod data;

#[cfg(test)]
mod test;

/// xlsx文件分组输出器
///
/// 主要功能功能：
///
/// 1. 自动分组写入不同xlsx文件中
///
/// 自动对数据新分组，并按照不同的分组写入到不同的xlsx文件中///
///
/// 2. 提供灵活的数据写入模式
///
/// xlxs每行数据在写入时，可以通过两种模式进行自定义写入：
///
/// * 快捷模式 : 只需要提供将原始数据转换为待写入excel数据的函数即可，无需手工进行excel的写入操作
/// * 高级模式 : 完全有用户自行调用xlsx相关api进行数据写入，实现最大灵活性
///
/// 3. 可根据模板xlsx文件生成输出excel文件
///
/// 在模板文件中可优先编辑好表标题、表头等信息
///
/// 如果未使用模板，则需要提供TABLE_HEADER,一边自动生成表头
///
/// 4. 对xlsx文件进行加密
///
/// 写入时，支持对xlsx文件进行加密存储
///
/// 5. 可在分组时，同时保持包含所有数据的合并xlsx文件
///
/// 6. 可灵活确定文件存储名称
///
/// * OUTPUT_FILE_NAME_GETTER 完全自定义实现任意文件名写入
/// * DEFAULT_FILE_NAME_PREF 系统自动以该变量为基础生成文件名,可自动在导出文件名称中增加导出日期
///
pub trait XlsxGroupWrite {
    /// 每一行数据的xlsx对应行的各列数据的方法
    ///
    /// 自动遍历数据，并调用该方法写入xlsx数据
    ///
    /// 两种模式：
    ///
    /// 1. 高级模式
    ///
    /// 调用Self::line_writer_advance
    ///
    /// 可完整自行控制如何写入xlsx数据，比如合并写入、自定义写入格式等
    ///
    /// 2. 简便模式
    ///
    /// 调用Self::line_writer_simple
    ///
    /// 大部分时候excel写入时都是一个数据写入一列
    /// 这时候如果还得通过LINE_WRITER自己通过xlsx相关api写入单元格数据
    /// 起始没有必要。
    ///
    /// 对于如上情况，可通过该数据转换器，直接根据返回的数据，自动写入xlsx单元格中
    /// 终端用户不需要了解xlsx写入的API，进一步降低编码难度和智能化水平
    ///
    /// 只支持每个数据写入一列
    /// 如需要更加自由的，比如合并写入单元格、自定义格式等，请使用 LINE_WRITER ，并将此值设置为None
    ///
    const LINE_WRITER_MODEL: XlsxLineWriterModel;
    /// 需要传递的额外参数类型
    /// 用于向文件名称生成函数、额外信息写入函数等传入个性化参数
    type ExtraArgType;
    /// 每一行数据的xlsx对应行的各列数据的方法
    ///
    /// 自动遍历数据，并调用该方法写入xlsx数据
    /// 2. 简便模式
    ///
    /// 大部分时候excel写入时都是一个数据写入一列
    /// 这时候如果还得通过LINE_WRITER自己通过xlsx相关api写入单元格数据
    /// 起始没有必要。
    ///
    /// 对于如上情况，可通过该数据转换器，直接根据返回的数据，自动写入xlsx单元格中
    /// 终端用户不需要了解xlsx写入的API，进一步降低编码难度和智能化水平
    ///
    /// 只支持每个数据写入一列
    /// 如需要更加自由的，比如合并写入单元格、自定义格式等，请使用 line_write_advance
    ///
    /// # 参数说明
    ///
    /// * line_index 正在写入行的行号，行号从1开始计数。
    #[allow(unused_variables)]
    fn line_writer_simple(&self, line_index: u32) -> Vec<XlsxColValue> {
        unimplemented!()
    }
    /// 每一行数据的xlsx对应行的各列数据的方法
    ///
    /// 自动遍历数据，并调用该方法写入xlsx数据
    ///
    /// 高级模式
    ///
    /// 可完整自行控制如何写入xlsx数据，比如合并写入、自定义写入格式等
    ///
    /// # 参数说明
    ///
    /// * sheet 正在写入的xlsx工作表
    /// * line_index 正在写入行的行号，行号从1开始计数。
    #[allow(unused_variables)]
    fn line_writer_advance(
        &self,
        sheet: &mut Worksheet,
        line_index: u32,
    ) -> Option<XlsxLineAdvanceWriterResult> {
        unimplemented!()
    }
    /// 每一行数据的xlsx对应行的各列数据的方法 - 包含额外个性化参数
    ///
    /// 自动遍历数据，并调用该方法写入xlsx数据
    ///
    /// 高级模式
    ///
    /// 可完整自行控制如何写入xlsx数据，比如合并写入、自定义写入格式等
    ///
    /// # 参数说明
    ///
    /// * sheet 正在写入的xlsx工作表
    /// * line_index 正在写入行的行号，行号从1开始计数。
    /// * extra_arg 额外通过wirte传入的参数
    #[allow(unused_variables)]
    fn line_writer_advance_with_extra_arg(
        &self,
        sheet: &mut Worksheet,
        line_index: u32,
        extra_arg: Option<&Self::ExtraArgType>,
    ) -> Option<XlsxLineAdvanceWriterResult> {
        unimplemented!()
    }

    /// 获取输出xlsx文件模板
    ///
    /// 用于初始化表标题、表头等
    fn get_template() -> XlsxInitTemplet;

    /// 数据分组id生成器
    ///
    /// 根据原始数据生成分组id
    ///
    /// 判断是否需要单独输出到某一文件
    /// 如果需要输出到某一单独文件，自动从模板初始化XLSX Sheet.
    /// 并将对应的sheet传入LINE_WRITER，实现数据输出
    ///
    /// 未设置则只输出合并文件，不分割输出
    fn group_make(&self) -> &str {
        unimplemented!()
    }
    /// 完全自定义的输出文件名称名称生成器
    ///
    /// 参数说明:
    ///
    /// * group_id ：当期数据的分组id
    #[allow(unused_variables)]
    fn get_output_file_name_advance(group_id: &str) -> String {
        Self::get_output_file_name_advance_with_extra_arg(group_id, None)
    }
    /// 完全自定义的输出文件名称名称生成器 - 传递额外个性化参数 -包含额外个性化参数
    ///
    /// 参数说明:
    ///
    /// * group_id ：当期数据的分组id
    /// * extra_arg 额外的个性化参数
    #[allow(unused_variables)]
    fn get_output_file_name_advance_with_extra_arg(
        group_id: &str,
        extra_arg: Option<&Self::ExtraArgType>,
    ) -> String {
        unimplemented!()
    }
    /// 固定模式的简单文件名称生成
    ///
    /// 生成文件名称格式：特定前缀-分组id-输出日期
    /// 输出文件名称获取器
    /// 用于复杂文件名称的完全自定义输出
    ///
    /// None 则使用 get_output_file_name_advance 获取文件名称
    const OUTPUT_FILE_NAME_GETTER_SIMPLE: Option<OutputFileNameSimpleGetter> = None;

    /// 对导出的xlsx文件进行一些个性化的整体修改(数据引用版本)
    /// 比如需要在第二行插入对应分组名称，插入报表数据范围等信息
    ///
    /// 将在xlsx初始化完成后自动调用该方法
    ///
    /// 默认不做任何处理，后续如果需要则在实现trait时自行覆盖该方法
    ///
    /// # 参数说明
    ///
    /// * sheet 要修改的xlsx工作表
    /// * group_id 该xlsx对应的分组id
    #[allow(unused_variables)]
    fn add_custom_info_to_sheet(sheet: &mut Worksheet, group_id: &str) {
        Self::add_custom_info_to_sheet_with_extra_arg(sheet, group_id, None)
    }
    /// 对导出的xlsx文件进行一些个性化的整体修改(数据引用版本) - 包含额外个性化参数
    /// 比如需要在第二行插入对应分组名称，插入报表数据范围等信息
    ///
    /// 将在xlsx初始化完成后自动调用该方法
    ///
    /// 默认不做任何处理，后续如果需要则在实现trait时自行覆盖该方法
    ///
    /// # 参数说明
    ///
    /// * sheet 要修改的xlsx工作表
    /// * group_id 该xlsx对应的分组id
    /// * extra_arg 额外的个性化参数
    #[allow(unused_variables)]
    fn add_custom_info_to_sheet_with_extra_arg(
        sheet: &mut Worksheet,
        group_id: &str,
        extra_arg: Option<&Self::ExtraArgType>,
    ) {
        // 不做任何处理，后续如果时请覆盖
    }
    /// 自动对数据进行分组，并按照不同分组写入不同EXCEL XLSX文件中(数据引用版本)-包含额外个性化参数
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * output_model 输出合并XLSX文件的类型，控制是否分组、合并等输出
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_ref_with_extra_arg(
        data: &[&Self],
        output_model: XlsxWriteModel,
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>> {
        // 将写入的xlsx文件清单
        let mut output_xlsx_files: Vec<OutputXlsxFile> = Vec::new();
        // 初始化合并文件
        let merge_sheet_id = "合并";
        let template = Self::get_template();
        let merge_file_name =
            if let Some(output_file_name_getter_simple) = Self::OUTPUT_FILE_NAME_GETTER_SIMPLE {
                output_file_name_getter_simple.get_save_file_name(merge_sheet_id)
            } else {
                // 是否有额外参数
                if std::any::type_name::<()>() == std::any::type_name::<Self::ExtraArgType>() {
                    Self::get_output_file_name_advance(merge_sheet_id)
                } else {
                    Self::get_output_file_name_advance_with_extra_arg(
                        merge_sheet_id,
                        extra_arg.as_ref(),
                    )
                }
            };
        let mut merge_xlsx_file = template.init_new_xlsx(merge_sheet_id, &merge_file_name, true)?;
        // 保存基础xlsx文件，后续使用该文件进行clone，以便只读取一次模板文件读取次数，提升性能
        let base_xlsx_file = merge_xlsx_file.clone_to_new("nope", "nope", false);
        let merge_sheet = merge_xlsx_file
            .excel_book
            .get_sheet_mut(&0)
            .ok_or_else(|| anyhow!(" 初始化汇总xlsx失败"))?;
        // 添加个性化信息
        if std::any::type_name::<()>() == std::any::type_name::<Self::ExtraArgType>() {
            Self::add_custom_info_to_sheet(merge_sheet, merge_sheet_id);
        } else {
            Self::add_custom_info_to_sheet_with_extra_arg(
                merge_sheet,
                merge_sheet_id,
                extra_arg.as_ref(),
            );
        }
        // 临时初始化需要写入的xlsx文件，以避免rust未初始错误
        // 后续真实写入数据时会自动替换为实际需要写入的xlsx文件
        let mut cur_xlsx_file = &mut base_xlsx_file.clone_to_new("nope", "will_drop", false);
        let mut cur_sheet = cur_xlsx_file
            .excel_book
            .get_sheet_mut(&0)
            .ok_or_else(|| anyhow!("读取Nope待写入excel表格失败"))?;
        for line in data {
            let cur_group_id = if output_model != XlsxWriteModel::MergeOnly {
                line.group_make()
            } else {
                "sum"
            };
            // 写入分组数据
            if output_model != XlsxWriteModel::MergeOnly {
                // 将写入的数据与之前的分类不一致，需要获取新的xlsx文件中
                if cur_xlsx_file.id != cur_group_id {
                    // 获取待写入xlsx文件
                    cur_xlsx_file = match output_xlsx_files
                        .iter_mut()
                        .find(|xlsx_file| xlsx_file.id == cur_group_id)
                    {
                        Some(xlsx_file) => xlsx_file,
                        None => {
                            let new_file_name = if let Some(output_file_name_getter_simple) =
                                Self::OUTPUT_FILE_NAME_GETTER_SIMPLE
                            {
                                output_file_name_getter_simple.get_save_file_name(cur_group_id)
                            } else {
                                Self::get_output_file_name_advance(cur_group_id)
                            };

                            let xlsx_file =
                                base_xlsx_file.clone_to_new(cur_group_id, &new_file_name, false);
                            output_xlsx_files.push(xlsx_file);
                            let last_index = output_xlsx_files.len() - 1;
                            output_xlsx_files.get_mut(last_index).unwrap()
                        }
                    };

                    cur_sheet = cur_xlsx_file
                        .excel_book
                        .get_sheet_mut(&0)
                        .ok_or_else(|| anyhow!("读取待写入excel表格失败"))?;

                    // 添加个性化信息
                    if std::any::type_name::<()>() == std::any::type_name::<Self::ExtraArgType>() {
                        Self::add_custom_info_to_sheet(cur_sheet, cur_group_id);
                    } else {
                        Self::add_custom_info_to_sheet_with_extra_arg(
                            cur_sheet,
                            cur_group_id,
                            extra_arg.as_ref(),
                        );
                    }
                }
                // 在分类表格中写入数据
                match Self::LINE_WRITER_MODEL {
                    XlsxLineWriterModel::Advance => {
                        // 高级模式，自定义写入
                        match if std::any::type_name::<()>()
                            == std::any::type_name::<Self::ExtraArgType>()
                        {
                            line.line_writer_advance(cur_sheet, cur_xlsx_file.index)
                        } else {
                            line.line_writer_advance_with_extra_arg(
                                cur_sheet,
                                cur_xlsx_file.index,
                                extra_arg.as_ref(),
                            )
                        } {
                            Some(XlsxLineAdvanceWriterResult::Break) => {
                                // 增加1行
                                cur_xlsx_file.index += 1;
                                cur_xlsx_file.data_lines += 1;
                                break;
                            }
                            Some(XlsxLineAdvanceWriterResult::Continue) => {
                                // 增加1行
                                cur_xlsx_file.index += 1;
                                cur_xlsx_file.data_lines += 1;
                                continue;
                            }
                            None => {
                                cur_xlsx_file.index += 1;
                                cur_xlsx_file.data_lines += 1;
                            }
                        }
                    }
                    XlsxLineWriterModel::Simple => {
                        // 简易模式，快速写入
                        let line_data = line.line_writer_simple(cur_xlsx_file.index);
                        XlsxColValue::write_line_data_simple(
                            cur_sheet,
                            cur_xlsx_file.index,
                            &line_data,
                        )?;
                        cur_xlsx_file.index += 1;
                        cur_xlsx_file.data_lines += 1;
                    }
                }
            }

            // 写入汇总数据

            if output_model != XlsxWriteModel::GroupOnly {
                // 在表格中写入数据
                match Self::LINE_WRITER_MODEL {
                    XlsxLineWriterModel::Advance => {
                        // 高级模式，自定义写入
                        match if std::any::type_name::<()>()
                            == std::any::type_name::<Self::ExtraArgType>()
                        {
                            line.line_writer_advance(merge_sheet, merge_xlsx_file.index)
                        } else {
                            line.line_writer_advance_with_extra_arg(
                                merge_sheet,
                                merge_xlsx_file.index,
                                extra_arg.as_ref(),
                            )
                        } {
                            Some(XlsxLineAdvanceWriterResult::Break) => {
                                // 增加1行
                                merge_xlsx_file.index += 1;
                                merge_xlsx_file.data_lines += 1;
                                break;
                            }
                            Some(XlsxLineAdvanceWriterResult::Continue) => {
                                // 增加1行
                                merge_xlsx_file.index += 1;
                                merge_xlsx_file.data_lines += 1;
                                continue;
                            }
                            None => {
                                merge_xlsx_file.index += 1;
                                merge_xlsx_file.data_lines += 1;
                            }
                        }
                    }
                    XlsxLineWriterModel::Simple => {
                        // 简易模式，快速写入
                        let line_data = line.line_writer_simple(merge_xlsx_file.index);
                        XlsxColValue::write_line_data_simple(
                            merge_sheet,
                            merge_xlsx_file.index,
                            &line_data,
                        )?;
                        merge_xlsx_file.index += 1;
                        merge_xlsx_file.data_lines += 1;
                    }
                }
            }
        }
        // 保存文件
        let mut output_file_name_list: Vec<XlsxGroupWriteResp> =
            Vec::with_capacity(output_xlsx_files.len());
        // 保存分组文件
        if output_model != XlsxWriteModel::MergeOnly {
            for xlsx_file in &output_xlsx_files {
                // 保存xlsx文件
                xlsx_file.save(
                    #[cfg(feature = "encrypt")]
                    password,
                )?;
                output_file_name_list.push(xlsx_file.into())
            }
        }
        // 保存合并文件
        if output_model != XlsxWriteModel::GroupOnly {
            merge_xlsx_file.save(
                #[cfg(feature = "encrypt")]
                password,
            )?;
            output_file_name_list.push(merge_xlsx_file.into());
        }
        Ok(output_file_name_list)
    }
    /// 自动对数据进行分组，并按照不同分组写入不同EXCEL XLSX文件中(数据引用版本)
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * output_model 输出合并XLSX文件的类型，控制是否分组、合并等输出
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_ref(
        data: &[&Self],
        output_model: XlsxWriteModel,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>> {
        Self::write2xlsx_ref_with_extra_arg(
            data,
            output_model,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 自动对数据进行分组，并按照不同分组写入不同EXCEL XLSX文件中-包含额外个性化参数
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * output_model 输出合并XLSX文件的类型，控制是否分组、合并等输出
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_with_extra_arg(
        data: &[Self],
        output_model: XlsxWriteModel,
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        let data: Vec<&Self> = data.iter().collect();
        Self::write2xlsx_ref_with_extra_arg(
            &data,
            output_model,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 自动对数据进行分组，并按照不同分组写入不同EXCEL XLSX文件中
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * output_model 输出合并XLSX文件的类型，控制是否分组、合并等输出
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx(
        data: &[Self],
        output_model: XlsxWriteModel,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_with_extra_arg(
            data,
            output_model,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }

    /// 只导出汇总xlsx文件-包含额外个性化参数
    /// 即所有数据导出到一个xlsx文件中，不分组拆分
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件名称清单
    fn write2xlsx_merge_only_with_extra_arg(
        data: &[Self],
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_with_extra_arg(
            data,
            XlsxWriteModel::MergeOnly,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 只导出汇总xlsx文件
    /// 即所有数据导出到一个xlsx文件中，不分组拆分
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件名称清单
    fn write2xlsx_merge_only(
        data: &[Self],
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_merge_only_with_extra_arg(
            data,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }

    /// 只导出汇总xlsx文件(数据引用版本)-包含额外个性化参数
    /// 即所有数据导出到一个xlsx文件中，不分组拆分
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件名称清单
    fn write2xlsx_merge_only_ref_with_extra_arg(
        data: &[&Self],
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_ref_with_extra_arg(
            data,
            XlsxWriteModel::MergeOnly,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 只导出汇总xlsx文件(数据引用版本)
    /// 即所有数据导出到一个xlsx文件中，不分组拆分
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件名称清单
    fn write2xlsx_merge_only_ref(
        data: &[&Self],
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_merge_only_ref_with_extra_arg(
            data,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }

    /// 只导出分组拆分后的xlsx文件-包含额外个性化参数
    /// 不导出汇总的xlsx文件
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_group_only_with_extra_arg(
        data: &[Self],
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_with_extra_arg(
            data,
            XlsxWriteModel::GroupOnly,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 只导出分组拆分后的xlsx文件
    /// 不导出汇总的xlsx文件
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_group_only(
        data: &[Self],
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_group_only_with_extra_arg(
            data,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }

    /// 只导出分组拆分后的xlsx文件(数据引用版本)-包含额外个性化参数
    /// 不导出汇总的xlsx文件
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_group_only_ref_with_extra_arg(
        data: &[&Self],
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_ref_with_extra_arg(
            data,
            XlsxWriteModel::GroupOnly,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 只导出分组拆分后的xlsx文件(数据引用版本)
    /// 不导出汇总的xlsx文件
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_group_only_ref(
        data: &[&Self],
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_group_only_ref_with_extra_arg(
            data,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }

    /// 只导出分组拆分后的xlsx文件和汇总的xlsx文件-包含额外个性化参数
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_all_with_extra_arg(
        data: &[Self],
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_with_extra_arg(
            data,
            XlsxWriteModel::MergeAndGroup,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }

    /// 只导出分组拆分后的xlsx文件和汇总的xlsx文件
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_all(
        data: &[Self],
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_all_with_extra_arg(
            data,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 只导出分组拆分后的xlsx文件和汇总的xlsx文件(数据引用版本)-包含额外个性化参数
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_all_ref_with_extra_arg(
        data: &[&Self],
        extra_arg: Option<Self::ExtraArgType>,
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_ref_with_extra_arg(
            data,
            XlsxWriteModel::MergeAndGroup,
            extra_arg,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
    /// 只导出分组拆分后的xlsx文件和汇总的xlsx文件(数据引用版本)
    ///
    /// # 参数说明
    ///
    /// * data 要写入的数据
    /// * extra_arg 需要传入的额外自定义参数，将会传递到文件名称获取、写入自定义信息等方法中
    /// * password 加密密码，None则不加密 (需要添加encrypt特性)
    ///
    /// # 返回说明
    ///
    /// 返回成功写出的xlsx文件清单
    fn write2xlsx_all_ref(
        data: &[&Self],
        #[cfg(feature = "encrypt")] password: Option<&str>,
    ) -> Result<Vec<XlsxGroupWriteResp>>
    where
        Self: Sized,
    {
        Self::write2xlsx_all_ref_with_extra_arg(
            data,
            None,
            #[cfg(feature = "encrypt")]
            password,
        )
    }
}

pub mod prelude;
